package org.ne.framework.data.sql;

import org.ne.framework.data.annotation.Id;
import org.ne.framework.data.core.OrmPersistence;
import org.ne.framework.data.model.DbModel;
import org.ne.framework.data.util.ChkTools;
import org.ne.framework.data.util.ClassTools;
import org.ne.framework.data.util.GenerateTools;
import org.ne.framework.data.util.MysqlOrmTools;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.support.rowset.SqlRowSet;
import org.springframework.jdbc.support.rowset.SqlRowSetMetaData;
import org.springframework.stereotype.Service;

import java.lang.reflect.Field;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class OrmComponent implements OrmPersistence {

	@Autowired
	protected JdbcTemplate jt;

	@Override
	public void saveObj(DbModel obj) {
		String sql = MysqlOrmTools.getInsSQL(obj.getClass());
		// 设置id
		Field id = ClassTools.getIdField(obj.getClass());
		Object idVal = ClassTools.getClassVal(id, obj);
		if (idVal == null) {
			// idVal = GenerateTools.getUUID();
			// 用压缩版的 id
			idVal = GenerateTools.getBase58ID();
			ClassTools.setClassVal(id, obj, idVal);
		}
		// 程序 设置时间戳
		Field createdField = ClassTools.getCreatedField(obj.getClass());
		if (null != createdField) {
			Timestamp created = new Timestamp(System.currentTimeMillis());
			ClassTools.setClassVal(createdField, obj, created);
		}

		List<Object> vals = MysqlOrmTools.getValuesPar(obj);
		jt.update(sql, vals.toArray());
	}

	@Override
	public void updateObj(DbModel obj) {
		if (obj == null) {
			return;
		}
		String sql = MysqlOrmTools.getUpdateSQL(obj.getClass());

		List<Object> vals = new ArrayList<Object>();
		List<Field> fields = ClassTools.getClassFields(obj.getClass());
		Field id = null;
		for (Field field : fields) {
			if (field.isAnnotationPresent(Id.class)) {
				id = field;
				continue;
			}
			vals.add(ClassTools.getClassVal(field, obj));
		}
		vals.add(ClassTools.getClassVal(id, obj));

		jt.update(sql, vals.toArray());

	}

	@Override
	public void delObjById(Object id, Class<?> clazz) {
		String sql = MysqlOrmTools.getDelSQL(clazz);
		jt.update(sql, new Object[] { id });
	}

	@Override
	public void delObj(DbModel obj) {
		if (obj == null) {
			return;
		}
		Field id = ClassTools.getIdField(obj.getClass());
		Object val = ClassTools.getClassVal(id, obj);

		delObjById(val, obj.getClass());
	}

	@Override
	public void delRealObj(DbModel obj) {
		if (obj == null) {
			return;
		}
		Field id = ClassTools.getIdField(obj.getClass());
		Object val = ClassTools.getClassVal(id, obj);

		delRealObjById(val, obj.getClass());
	}

	@Override
	public void delRealObjById(Object id, Class<?> clazz) {
		if (ChkTools.isNull(id)) {
			return;
		}
		String sql = MysqlOrmTools.getDelRealSQL(clazz);
		jt.update(sql, new Object[] { id });
	}

	@Override
	public DbModel findObjById(String _id, Class<?> clazz) {
		if (ChkTools.isNull(_id)) {
			return null;
		}
		String sql = MysqlOrmTools.getSelectSQL(clazz, true);

		DbModel model = this.findObj(sql, new String[] { _id }, clazz);
		return model;
	}

	@Override
	public DbModel findObj(String sql, Class<?> clazz) {
		return findObj(sql, null, clazz);
	}

	@Override
	public DbModel findObj(String sql, Object[] args, final Class<?> clazz) {

		SqlRowSet rs = jt.queryForRowSet(sql, args);
		if (rs.next()) {
			Map<String, Object> map = new HashMap<String, Object>();
			SqlRowSetMetaData metaData = rs.getMetaData();
			int columnCount = metaData.getColumnCount();
			for (int i = 1; i <= columnCount; i++) {
				String label = metaData.getColumnLabel(i);
				Object val = rs.getObject(i);

				map.put(label, val);
			}
			DbModel model = ClassTools.trunMapToObj(map, clazz);
			return model;
		}

		return null;
	}
	
	public static void main(String[] args) {
		for (int i = 0; i < 10000; i++) {
			
			System.err.println(GenerateTools.getBase58ID().length());
		}
	}
}
